<template>
  <div class="blog-detail blog-theme">
    <el-breadcrumb separator="▶" class="breadcrumb">
      <el-breadcrumb-item to="/c-oj/home/blog">博客</el-breadcrumb-item>
      <el-breadcrumb-item>{{ article.title || "文章详情" }}</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 头部卡片已移至中间列 -->
    <el-row :gutter="16" class="content-row">
      <!-- 左侧：用户信息与热门推荐 -->
      <el-col :xs="24" :md="4">
        <aside class="left-sidebar">
          <el-card shadow="never" class="user-info">
            <el-avatar :size="64" src="/path/to/avatar.jpg" />
            <div class="username">用户名</div>
            <div class="bio">这里是用户的个人简介...</div>
          </el-card>

          <el-card shadow="never" class="hot-articles">
            <template #header>
              <div class="card-header">热门文章推荐</div>
            </template>
            <ul class="hot-article-list">
              <li
                v-for="ha in hotArticles"
                :key="ha.id"
                class="hot-article-item"
              >
                <div class="title">{{ ha.title }}</div>
                <div class="summary">{{ ha.summary }}</div>
              </li>
            </ul>
          </el-card>
        </aside>
      </el-col>

      <!-- 中间：头部 + 文章与评论 -->
      <el-col :xs="24" :md="16">
        <el-card class="header" shadow="never">
          <div class="title">{{ article.title }}</div>
          <div class="meta">
            <el-avatar :size="32" :src="article.author.avatar" />
            <span class="author">{{ article.author.name }}</span>
            <el-button type="primary" round size="small" class="ml8"
              >关注</el-button
            >
            <span class="ml8">发布于 {{ article.publishTime }}</span>
            <span class="ml8">阅读 {{ article.readCount }}</span>
            <span class="ml8">点赞 {{ article.likeCount }}</span>
          </div>
          <div class="tags">
            <el-tag
              v-for="t in article.tags"
              :key="t"
              type="success"
              size="small"
              >{{ t }}</el-tag
            >
          </div>
          <el-progress
            :percentage="progress"
            status="success"
            :stroke-width="6"
          />
        </el-card>
        <main class="main-content">
          <el-card class="article-box" shadow="never">
            <div class="article-content" ref="articleRef" v-html="html"></div>
          </el-card>

          <div class="actions">
            <el-button type="primary" @click="handleLike">点赞</el-button>
            <el-button @click="handleFavorite">收藏</el-button>
            <el-button>分享</el-button>
          </div>

          <el-card class="comment-box" shadow="never">
            <template #header>
              <div class="card-header">评论区</div>
            </template>
            <div class="comment-input">
              <el-input
                v-model="commentText"
                type="textarea"
                :rows="4"
                placeholder="发表你的看法..."
              />
              <div class="actions">
                <el-button type="primary" @click="handlePostComment"
                  >提交评论</el-button
                >
              </div>
            </div>
            <div class="comment-list">
              <el-empty
                v-if="comments.length === 0"
                description="还没有评论，来当第一个吧~"
              />
              <div v-else>
                <div v-for="c in comments" :key="c.id" class="comment-item">
                  <div class="comment-meta">
                    <el-avatar :size="28" :src="c.user.avatar" />
                    <span class="name">{{ c.user.name }}</span>
                    <span class="time">{{ c.time }}</span>
                    <el-button link type="primary">回复</el-button>
                    <el-button link>点赞 {{ c.likeCount }}</el-button>
                  </div>
                  <div class="content">{{ c.content }}</div>
                  <div v-if="c.replies && c.replies.length" class="reply-list">
                    <div v-for="r in c.replies" :key="r.id" class="reply-item">
                      <span class="r-name">{{ r.user.name }}</span>
                      <span class="r-time">{{ r.time }}</span>
                      <div class="r-content">{{ r.content }}</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </el-card>
        </main>
      </el-col>

      <!-- 右侧：目录导航（粘性） -->
      <el-col :xs="24" :md="4">
        <aside class="right-sidebar">
          <el-card shadow="never" class="toc sticky">
            <template #header>
              <div class="card-header">文章目录</div>
            </template>
            <el-tree
              :data="tocData"
              :props="tocProps"
              node-key="id"
              highlight-current
              :current-node-key="activeId"
              @node-click="scrollToSection"
            />
          </el-card>
        </aside>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, nextTick, watch } from "vue";
import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import {
  fetchArticleDetail,
  fetchComments,
  likeArticle,
  favoriteArticle,
  postComment,
} from "@/apis/blog";
import { marked } from "marked";

const route = useRoute();
const articleId = route.params.id;
const loading = ref(false);

const article = ref({
  title: "",
  author: { name: "", avatar: "" },
  publishTime: "",
  readCount: 0,
  likeCount: 0,
  tags: [],
  content: "",
});
const html = ref("");
const progress = ref(0);
const comments = ref([]);
const commentText = ref("");
const articleRef = ref(null);

const hotArticles = ref([
  { id: 1, title: "热门文章1", summary: "这是热门文章1的简介..." },
  { id: 2, title: "热门文章2", summary: "这是热门文章2的简介..." },
  { id: 3, title: "热门文章3", summary: "这是热门文章3的简介..." },
]);

const tocData = ref([
  { label: "章节1", id: "section-1" },
  { label: "章节2", id: "section-2" },
]);
const tocProps = { label: "label" };
const activeId = ref("");

function scrollToSection(node) {
  const section = document.getElementById(node.id);
  if (section) {
    section.scrollIntoView({ behavior: "smooth", block: "start" });
  }
}

function buildToc() {
  const root = articleRef.value;
  if (!root) return;
  const hs = Array.from(root.querySelectorAll("h1,h2,h3"));
  tocData.value = hs.map((el) => {
    if (!el.id) el.id = "h-" + Math.random().toString(36).slice(2);
    return { label: el.textContent?.trim() || "", id: el.id };
  });
}

let headingObserver;
function observeHeadings() {
  const root = articleRef.value;
  if (!root) return;
  const hs = root.querySelectorAll("h1,h2,h3");
  headingObserver = new IntersectionObserver(
    (entries) => {
      const visible = entries
        .filter((e) => e.isIntersecting)
        .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
      if (visible[0]?.target?.id) activeId.value = visible[0].target.id;
    },
    { root, rootMargin: "0px 0px -70% 0px", threshold: 0.1 }
  );
  hs.forEach((h) => headingObserver.observe(h));
}

async function loadDetail() {
  loading.value = true;
  try {
    const [aRes, cRes] = await Promise.all([
      fetchArticleDetail(articleId),
      fetchComments(articleId),
    ]);
    article.value = aRes.data;
    html.value = marked.parse(article.value.content || "");
    comments.value = cRes.data;
  } catch (e) {
    ElMessage.error("文章加载失败");
  } finally {
    loading.value = false;
  }
}

function onScroll() {
  const el = document.querySelector(".article-content");
  if (!el) return;
  const total = el.scrollHeight - el.clientHeight;
  const scrolled = el.scrollTop;
  progress.value = total > 0 ? Math.round((scrolled / total) * 100) : 0;
}

function handleLike() {
  likeArticle(articleId).then(() => {
    article.value.likeCount++;
  });
}

function handleFavorite() {
  favoriteArticle(articleId).then(() => {
    ElMessage.success("已收藏");
  });
}

async function handlePostComment() {
  if (!commentText.value.trim()) return ElMessage.warning("请输入评论内容");
  await postComment(articleId, { content: commentText.value });
  commentText.value = "";
  const cRes = await fetchComments(articleId);
  comments.value = cRes.data;
}

onMounted(async () => {
  await loadDetail();
  await nextTick();
  const el = articleRef.value;
  el && el.addEventListener("scroll", onScroll);
  buildToc();
  observeHeadings();
});
onBeforeUnmount(() => {
  const el = articleRef.value;
  el && el.removeEventListener("scroll", onScroll);
  if (headingObserver) headingObserver.disconnect();
});

watch(html, async () => {
  await nextTick();
  buildToc();
  observeHeadings();
});
</script>

<style lang="scss" scoped>
.blog-detail {
  width: 100%;
  margin: 0 auto;
  padding: 16px 24px 48px;
  margin-top: -60px;
}
.breadcrumb {
  margin-bottom: 4px;
}
.header .title {
  font-size: 24px;
  font-weight: 700;
  color: var(--text-color);
  margin-bottom: 6px;
}
.header .meta {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #7f8c8d;
}
.header .tags {
  margin: 8px 0;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.header .actions {
  margin-top: 8px;
  display: flex;
  gap: 8px;
}
.content-row {
  margin-top: 16px;
}

.left-sidebar .user-info {
  text-align: center;
  margin-bottom: 16px;
}
.username {
  font-size: 18px;
  font-weight: bold;
  margin-top: 8px;
}
.bio {
  font-size: 14px;
  color: #7f8c8d;
  margin-top: 4px;
}

.hot-articles .hot-article-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.hot-articles .hot-article-item {
  padding: 8px 0;
  border-bottom: 1px solid #eee;
}
.hot-articles .hot-article-item:last-child {
  border-bottom: none;
}

.article-box {
  margin-bottom: 16px;
}
.article-content {
  max-width: 880px;
  margin: 0 auto;
  max-height: 60vh;
  overflow: auto;
  padding-right: 10px;
  line-height: 1.6;
}
.article-content img {
  display: block;
  max-width: 100%;
  margin: 16px auto;
  border-radius: 6px;
}
.comment-box {
  margin-top: 16px;
}
.comment-input .actions {
  margin-top: 8px;
  display: flex;
  justify-content: flex-end;
}
.comment-item {
  padding: 10px 0;
  border-bottom: 1px solid #eee;
}
.comment-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #7f8c8d;
}
.comment-meta .name {
  font-weight: 600;
  color: var(--text-color);
}
.reply-list {
  margin-left: 36px;
  background: #fafafa;
  padding: 8px;
  border-radius: 8px;
}
.reply-item {
  margin: 6px 0;
}

.toc.sticky {
  position: sticky;
  top: 72px; /* 顶部导航高度预留 */
  max-height: calc(100vh - 88px);
  overflow-y: auto;
}

@media (max-width: 768px) {
  .article-content {
    max-height: unset;
  }
  .right-sidebar {
    display: none;
  }
}
</style>
